package com.jq.jqaicode.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.jq.jqaicode.common.AppConstant;
import com.jq.jqaicode.common.file.CodeParserSaveTemplate;
import com.jq.jqaicode.model.entity.AiApp;
import com.jq.jqaicode.service.AiAppService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.HandlerMapping;

import java.io.File;


/**
 * 静态资源访问
 */
@RestController
@RequestMapping("/static")
public class StaticResourceController {

    // 应用生成根目录（用于浏览）
    private static final String PREVIEW_ROOT_DIR = AppConstant.CODE_OUTPUT_ROOT_DIR;

    @Autowired
    AiAppService aiAppService;

    /**
     * 提供静态资源访问，支持目录重定向
     * 访问格式：http://localhost:8123/api/static/{deployKey}[/{fileName}]
     */
    @GetMapping("/{deployKey}/**")
    public ResponseEntity<Resource> serveStaticResource(
            @PathVariable String deployKey,
            HttpServletRequest request) {
        try {
            // 获取资源路径
            String resourcePath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
            resourcePath = resourcePath.substring(("/static/" + deployKey).length());
            // 如果是目录访问（不带斜杠），重定向到带斜杠的URL
            if (resourcePath.isEmpty()) {
                HttpHeaders headers = new HttpHeaders();
                headers.add("Location", request.getRequestURI() + "/");
                return new ResponseEntity<>(headers, HttpStatus.MOVED_PERMANENTLY);
            }
            // 默认返回 index.html
            if (resourcePath.equals("/")) {
                resourcePath = "/index.html";
            }
            // 构建文件路径
            String filePath = PREVIEW_ROOT_DIR + "/" + deployKey + resourcePath;
            File file = new File(filePath);
            // 检查文件是否存在
            if (!file.exists()) {
                return ResponseEntity.notFound().build();
            }
            // 返回文件资源
            Resource resource = new FileSystemResource(file);
            return ResponseEntity.ok()
                    .header("Content-Type", getContentTypeWithCharset(filePath))
                    .body(resource);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }


    /**
     * 下载压缩包
     * @return
     */
    @PostMapping(value="/download", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ResponseEntity<byte[]> download(@RequestParam("appId") String appId){

        AiApp app = aiAppService.info(appId);
        if (app==null) {
            return ResponseEntity.notFound().build();
        }
        String buildUniqueDir = CodeParserSaveTemplate.buildUniqueDir(app.getId(), app.getCodeGenType());
        // 1. 源目录
        File srcDir = new File(buildUniqueDir);
        if (!srcDir.exists() || !srcDir.isDirectory()) {
            return ResponseEntity.notFound().build();
        }
        // 2. 生成 ZIP 临时文件
        File zipFile = new File(buildUniqueDir+ ".zip");
//        // 确保父目录存在
//        FileUtil.mkParentDirs(zipFile);
        // 3. 调用 Hutool5.8 的 Path 版 zip：第一个参数源目录，第二个参数目标 zip 文件
        //将aaa目录以及其目录下的所有文件目录打包到d:/bbb/目录下的ccc.zip文件中
        ZipUtil.zip(buildUniqueDir);

        // 4. 读取文件字节
        byte[] data = FileUtil.readBytes(zipFile);

        // 5. 准备 HTTP 响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentDisposition(
                ContentDisposition.attachment().filename(app.getId()+ ".zip").build()
        );
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        // 6. 删除临时文件（可选）
        FileUtil.del(zipFile);
        // 7. 返回 ResponseEntity
        return ResponseEntity
                .ok()
                .headers(headers)
                .body(data);
    }


    /**
     * 根据文件扩展名返回带字符编码的 Content-Type
     */
    private String getContentTypeWithCharset(String filePath) {
        if (filePath.endsWith(".html")) return "text/html; charset=UTF-8";
        if (filePath.endsWith(".css")) return "text/css; charset=UTF-8";
        if (filePath.endsWith(".js")) return "application/javascript; charset=UTF-8";
        if (filePath.endsWith(".png")) return "image/png";
        if (filePath.endsWith(".jpg")) return "image/jpeg";
        return "application/octet-stream";
    }
}
